import scala.math.BigInt

package chap2 {
  object chap2 {
    def fib(n: Int): BigInt = {
      @annotation.tailrec
      def loop(start: Int, end: Int, pree: BigInt, pre: BigInt): BigInt = {
        if (start > end) pre
        else
          start match {
            case 1 => loop(start + 1, end, 0, 1)
            case _ => loop(start + 1, end, pre, pree + pre)
          }
      }
      loop(0, n, BigInt(0), BigInt(0))
    }

    def partiall[A, B, C](a: A, f: (A, B) => C): B => C = (b: B) => f(a, b)

    def curry[A, B, C](f: (A, B) => C): A => (B => C) = (a: A) => partiall(a, f)

    def uncurry[A, B, C](f: A => B => C): (A, B) => C = (a: A, b: B) => f(a)(b)

    def compose[A, B, C](f: B => C, g: A => B): A => C = (a: A) => f(g(a))
  }
}